﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;

namespace CorporationWars
{
    [Serializable]
    public class UIKeyboard : UIControlBase
    {
        public bool IsVisible { get; set; }

        public string Title { get; set; }

        public List<UIACIIKey> keys { get; set; }
        protected Vector2 _Position { get; set; }
        public override Vector2 Position { get { return _Position; } set { _Position = value; SetupKeyboard(); } }

        Random rnd = new Random(DateTime.Now.Millisecond);

        [NonSerialized]
        public UIEvent OnReturn;

        string[] keyboardLayout = new string[] { 
            "1,2,3,4,5,6,7,8,9,0,bksp", 
            "Q,W,E,R,T,Y,U,I,O,P,minus", 
            "A,S,D,F,G,H,J,K,L, ,rtrn", 
            "Z,X,C,V,B,N,M,fullstop,underscore, ,kbClose" };

        public Color KeyColor { get; set; }
        public Color KeyHoverColor { get; set; }
        public Color KeyMouseDownColor { get; set; }
        public int KeyShadowHeight { get; set; }
        public int KeySize { get; set; }
        public int KeySpacing { get; set; }

        const int KeyBase = 73;

        public string Value { get; set; }

        public int MaxLen { get; set; }

        public UIKeyboard(Game1 game)
            : base(game, false)
        {
            KeySize = 32;
            KeySpacing = 8;
            KeyShadowHeight = 4;

            IsVisible = true;
            Value = string.Empty;

            MaxLen = 14;

            Title = "Enter Text:-";

            IsDragable = true;
        }
        public UIKeyboard(Game1 game, Color color, Color hoverColor, Color mouseDownColor, int shadowHeight = 4, int size = 32, int spacing = 8, string title = "") : this(game)
        {
            KeyColor = color;
            KeyHoverColor = hoverColor;
            KeyMouseDownColor = mouseDownColor;
            KeyShadowHeight = shadowHeight;
            KeySize = size;
            KeySpacing = spacing;

            if (title == string.Empty)
                title = "Enter Text:-";

            Title = title;            
        }

        protected void SetupKeyboard()
        {
            if (keys == null)
                keys = new List<UIACIIKey>();
            else
                keys.Clear();

            int lineNo = 0;
            foreach (string line in keyboardLayout)
            {
                string[] chars = line.Split(new char[] { ',' });
                int charNo = 0;
                foreach (string ch in chars)
                {
                    //if (ch != " ")
                    {
                        string tt = string.Empty;
                        Keys xnaKey = Keys.None;
                        bool needsShift = false;

                        switch (ch)
                        {
                            case "kbClose": 
                                tt = "Cancel...";
                                break;
                            case "rtrn":
                                tt = "Return...";
                                xnaKey = Keys.Enter;
                                break;
                            case "bksp":
                                tt = "Backspace...";
                                xnaKey = Keys.Back;
                                break;
                            case "fullstop":
                                tt = ".";
                                xnaKey = Keys.OemPeriod;
                                break;
                            case "minus":
                                tt = "-";
                                xnaKey = Keys.OemMinus;
                                break;
                            case "underscore":
                                tt = "_";
                                xnaKey = Keys.OemMinus;
                                needsShift = true;
                                break;
                            default:
                                tt = ch;
                                if (ch != " ")
                                {
                                    int tst = -1;
                                    if (int.TryParse(ch, out tst))
                                        xnaKey = (Keys)Enum.Parse(typeof(Keys), string.Format("D{0}", ch));
                                    else
                                        xnaKey = (Keys)Enum.Parse(typeof(Keys), ch);
                                }
                                break;
                        }
                        string k = string.Format("Textures/TypeFont/{0}", ch);

                        if (ch == " ")
                            k = "Textures/blank";

                        keys.Add(new UIACIIKey(Game)
                        {
                            Name = ch,
                            XNAKey = xnaKey,
                            KeyNeedsShift = needsShift,
                            Key = k,
                            Position = new Vector2(Position.X + ((KeySize + KeySpacing) * charNo), (Position.Y + KeyBase) + ((KeySize + KeySpacing) * lineNo)),
                            Color = KeyColor,
                            HoverColor = KeyHoverColor,
                            MouseDownColor = KeyMouseDownColor,
                            ShadowHeight = KeyShadowHeight,
                            Width = KeySize + KeySpacing,
                            Height = KeySize + KeySpacing,
                            OnClick = KeyPressed,
                            KeySpace = KeySpacing,
                            KeySize = this.KeySize,
                            ToolTipText = tt,
                        });
                    }
                    charNo++;
                }
                lineNo++;
            }
            keys.Add(new UIACIIKey(Game)
            {
                Name = "spbr",
                XNAKey = Keys.Space,
                KeyNeedsShift = false,
                Key = "Textures/TypeFont/spbr",
                Position = new Vector2(Position.X, Position.Y + (KeyBase) + 5 * KeySize),
                Color = KeyColor,
                HoverColor = KeyHoverColor,
                MouseDownColor = KeyMouseDownColor,
                ShadowHeight = KeyShadowHeight,
                Width = 11 * (this.KeySize + KeySpacing),
                Height = KeySize + KeySpacing,
                OnClick = KeyPressed,
                KeySpace = KeySpacing,
                KeySize = this.KeySize,
                ToolTipText = "Space...",
            });


            Width = (KeySize + KeySpacing) * 11;
            Height = (int)((KeySize + KeySpacing) * (keyboardLayout.Length + 1)) + 32 + KeySize + KeySpacing;
        }

        protected void KeyPressed(UIZone sender)
        {
            switch (sender.Name)
            {
                case "kbClose":
                    Value = string.Empty;
                    IsVisible = false;
                    break;
                case "rtrn":
                    if (OnReturn != null)
                        OnReturn(sender);
                    if (Game.AudioOn && Game.SFXOn)
                        Game.Content.Load<SoundEffect>("Audio/SFX/dtmf-hash").Play();
                    break;
                case "bksp":
                    if(Value.Length > 0)
                        Value = Value.Substring(0, Value.Length - 1);
                    if (Game.AudioOn && Game.SFXOn)
                        Game.Content.Load<SoundEffect>("Audio/SFX/dtmf-hash").Play();
                    break;
                case "spbr":
                    AddChar(" ");
                    if (Game.AudioOn && Game.SFXOn)
                        Game.Content.Load<SoundEffect>("Audio/SFX/dtmf-hash").Play();
                    break;
                case "fullstop":
                    AddChar(".");
                    if (Game.AudioOn && Game.SFXOn)
                        Game.Content.Load<SoundEffect>("Audio/SFX/dtmf-hash").Play();
                    break;
                case "minus":
                    AddChar("-");
                    if (Game.AudioOn && Game.SFXOn)
                        Game.Content.Load<SoundEffect>("Audio/SFX/dtmf-hash").Play();
                    break;
                case "underscore":
                    AddChar("_");
                    if (Game.AudioOn && Game.SFXOn)
                        Game.Content.Load<SoundEffect>("Audio/SFX/dtmf-hash").Play();
                    break;
                default :
                    AddChar(sender.Name);
                    int no = rnd.Next(0, 10);
                    if (Game.AudioOn && Game.SFXOn)
                        Game.Content.Load<SoundEffect>(string.Format("Audio/SFX/dtmf-{0}", no)).Play();
                    break;
            }
        }

        protected void AddChar(string ch)
        {
            if (Value.Length + 1 <= MaxLen)
                Value += ch;
        }

        public override void Update(GameTime gameTime)
        {
            if (!IsVisible)
                return;

            base.Update(gameTime);

            for(int k = keys.Count-1;k >= 0;k--)
                keys[k].Update(gameTime);

            // Am I in the list?
            Keys[] keysPressed = Game.LastPressedKeys();
            if (keysPressed != null && keysPressed.Length > 0)
            {
                UIACIIKey key = null;

                if (keysPressed.Length == 1)
                    key = keys.SingleOrDefault(entity => entity.XNAKey == keysPressed[0] && !entity.KeyNeedsShift);
                else
                {
                    // Is shift down?
                    if(keysPressed.Contains(Keys.LeftShift) || keysPressed.Contains(Keys.RightShift))
                        key = keys.SingleOrDefault(entity => entity.XNAKey == keysPressed[1] && entity.KeyNeedsShift);
               }

                if (key != null && Game.IsKeyPressed(key.XNAKey))
                    KeyPressed(key);
            }
        }

        public override void Draw(GameTime gameTime)
        {
            if (!IsVisible)
                return;

            SpriteBatch spriteBatch = (SpriteBatch)Game.Services.GetService(typeof(SpriteBatch));

            // Render Title
            spriteBatch.Draw(Game.Content.Load<Texture2D>("Textures/halfwhiteToNothing"), new Rectangle((int)Position.X, (int)Position.Y, Width, 32), Color.SteelBlue);
            Game.RenderText(Title, new Vector2(Position.X + 16, Position.Y + 8), Color.LightSteelBlue, -1, "Fonts/cyberpunkfont");

            // Render Text Output            
            float len = Game.Content.Load<SpriteFont>("Fonts/cyberpunkfont").MeasureString(Value).X;
            spriteBatch.Draw(Game.Content.Load<Texture2D>("Textures/halfWhite"), new Rectangle((int)Position.X, (int)Position.Y + 32, Width, (KeySize + KeySpacing)), Color.White);
            spriteBatch.Draw(Game.Content.Load<Texture2D>("Textures/textBoxBG"), new Rectangle((int)Position.X, (int)Position.Y + 32, Width, (KeySize + KeySpacing)), Color.White);
            Vector2 txtPos = new Vector2(Position.X + ((Width / 2) - (len / 2)), Position.Y + 32 + 12);

            Game.RenderText(Value, txtPos, KeyColor, -1, "Fonts/cyberpunkfont");

            spriteBatch.Draw(Game.Content.Load<Texture2D>("Textures/halfWhite"), new Rectangle((int)Position.X, (int)Position.Y + KeyBase - 1, Width, 1), Color.White);
            spriteBatch.Draw(Game.Content.Load<Texture2D>("Textures/halfWhite"), new Rectangle((int)Position.X, (int)Position.Y, Width, 1), Color.White);

            for (int k = keys.Count-1; k >= 0; k--)
                keys[k].Draw(gameTime);

            spriteBatch.Draw(Game.Content.Load<Texture2D>("Textures/halfWhite"), new Rectangle((int)Position.X, (int)Position.Y + KeyBase + ((KeySize + KeySpacing) * 5), Width, 1), Color.White);
        }
    }

    
}
